home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************
- ** mem.h **
- ** Memory-Handler **
- ** Speicherzugriffe, RAM,ROM,Hardware **
- *******************************************************/
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include "mem.h"
- #include "atari.h"
-
- #ifndef O_BINARY
- #define O_MODE O_RDONLY
- #else
- #define O_MODE (O_RDONLY | O_BINARY)
- #endif
-
- #ifdef VMS
- #include <unixio.h>
- #include <file.h>
- #else
- #include <fcntl.h>
- #endif
-
- mtype memory[65536];
- mtype *XE_Banks[5]; /* #5 is a temporary buffer */
- MemGet mget[65536];
- MemPut mput[65536];
-
- static struct Cart *current=NULL; /* currently inserted LEFT cartridge */
- static struct Cart *basic=NULL; /* XL,XE basic */
- static struct Cart *os=NULL; /* main OS, 0xe000,0xffff */
- static struct Cart *mpack=NULL; /* math pack, 0xd800,0xdfff */
- static struct Cart *os_x=NULL; /* XL OS extension 0xc000,0xcfff */
- static struct Cart *selftest=NULL; /* XL selftest 0xd000,0xd7ff */
-
- static int basic_on=FALSE;
-
- static char *rcsid = "$Id: mem.c,v 1.00 1998/02/17 thor";
-
- static struct Cart *ReadCart(char *filename, int fd,int addr, int nbytes);
-
-
-
- mtype NoGet(void)
- {
- return ~0;
- }
-
- int NoPut(mtype byte)
- {
- return 0;
- }
-
- void SetRAM(int lower,int upper)
- {
- int i;
-
- for(i=lower;i<=upper;i++) {
- mput[i] = NULL;
- mget[i] = NULL;
- }
- }
-
- void SetROM(int lower,int upper)
- {
- int i;
-
- for(i=lower;i<=upper;i++) {
- mput[i] = &NoPut;
- mget[i] = NULL;
- }
- }
-
- void SetHW(int addr,int mask,MemGet read,MemPut write)
- {
- int i;
- int lo,hi;
-
- lo = addr & 0xff00;
- hi = lo + 0x100;
-
- for(i=lo;i<hi;i++) {
- if ((i & mask)==addr) {
- if (read) mget[i] = read;
- else mget[i] = &NoGet;
-
- if (write) mput[i] = write;
- else mput[i] = &NoPut;
- }
- }
- }
-
-
- void SetBlank(int lower,int upper)
- {
- int i;
-
- for(i=lower;i<=upper;i++) {
- mget[i] = &NoGet;
- mput[i] = &NoPut;
- }
- }
-
-
- void EnablePILL (void)
- {
- SetROM (0x8000, 0xbfff);
- }
-
- void CopyFromMem(ATPtr from,UBYTE *to,int size)
- {
- memcpy(to,from+memory,size);
- }
-
-
- void CopyToMem(UBYTE *from,ATPtr to,int size)
- {
- int i;
-
- for(i=0;i<size;i++) {
- Poke(to,*from);
- from++,to++;
- }
- }
-
- struct Cart *AllocCart(int size)
- {
- struct Cart *ct;
- int i;
-
- if ((ct=malloc(sizeof(struct Cart)))!=0) {
- if ((ct->image=malloc(size*sizeof(mtype)))!=0) {
- if ((ct->saveback=malloc(size*sizeof(mtype)))!=0) {
- ct->type = 0;
- ct->active = FALSE;
- ct->num_secs = 1; /* Defaults to one section */
- for (i=0;i<0x4;i++) {
- ct->secs[i].lo = ct->secs[i].hi = 0;
- ct->secs[i].offset = 0;
- ct->secs[i].active = FALSE;
- }
- ct->secs[0].active = TRUE; /* section zero is active by default */
-
- return ct;
- }
- free(ct->image);
- }
- free(ct);
- }
-
- return NULL;
- }
-
- void FreeCart(struct Cart *ct)
- {
- if (ct) {
- if (ct->image)
- free(ct->image);
- if (ct->saveback)
- free(ct->saveback);
- free(ct);
- }
- }
-
- static int ReadImage(int fd,mtype *to,int nbytes)
- {
- UBYTE *buffer,*ptr;
- int i;
- int status=0;
-
- if ((buffer=malloc(nbytes*sizeof(UBYTE)))!=0) {
- if (read(fd,buffer,nbytes)==nbytes) {
- for(i=0,ptr=buffer;i<nbytes;i++,ptr++,to++)
- *to=*ptr;
- status = 1;
- }
- free(buffer);
- }
-
- return status;
- }
-
- int Read5200Rom(char *filename,int fd)
- {
- int fdo = -1;
- int status = 0;
-
- if ((os=AllocCart(0xffff-0xf800+1))!=0) {
- if (filename) {
- fd = fdo = open(filename, O_MODE, 0777);
- }
- if (fd >= 0) {
- if (ReadImage(fd,os->image,0xffff-0xf800+1)) {
- status = 1;
- }
- }
- }
-
- if (fdo >= 0)
- close(fdo);
-
- if (status) {
- os->secs[0].lo=0xf800;
- os->secs[0].hi=0xffff;
- return TRUE;
- }
-
- if (verbose)
- perror(filename);
-
- FreeCart(os);
-
- os=NULL;
-
- return FALSE;
- }
-
- int ReadOSABRom(char *filename,int fd)
- {
- int fdo = -1;
- int status = 0;
-
- if ((os=AllocCart(0xffff-0xe000+1))!=0) {
- if ((mpack=AllocCart(0xdfff-0xd800+1))!=0) {
- if (filename) {
- fd = fdo = open(filename, O_MODE, 0777);
- }
- if (fd >= 0) {
- if (ReadImage(fd,mpack->image,0xdfff-0xd800+1)) {
- if (ReadImage(fd,os->image,0xffff-0xe000+1)) {
- status = 1;
- }
- }
- }
- }
- }
-
- if (fdo >= 0)
- close(fdo);
-
- if (status) {
- os->secs[0].lo=0xe000;
- os->secs[0].hi=0xffff;
- mpack->secs[0].lo=0xd800;
- mpack->secs[0].hi=0xdfff;
- return TRUE;
- }
-
- if (verbose)
- perror(filename);
-
- FreeCart(os);
- FreeCart(mpack);
-
- os=mpack=NULL;
-
- return FALSE;
- }
-
- int ReadXLRom(char *filename,int fd)
- {
- int fdo = -1;
- int status = 0;
-
- if ((os=AllocCart(0xffff-0xe000+1))!=0) {
- if ((mpack=AllocCart(0xdfff-0xd800+1))!=0) {
- if ((os_x=AllocCart(0xcfff-0xc000+1))!=0) {
- if ((selftest=AllocCart(0xd7ff-0xd000+1))!=0) {
- if (filename) {
- fd = fdo = open(filename, O_MODE, 0777);
- }
- if (fd>=0) {
- if (ReadImage(fd,os_x->image,0xcfff-0xc000+1)) {
- if (ReadImage(fd,selftest->image,0xd7ff-0xd000+1)) {
- if (ReadImage(fd,mpack->image,0xdfff-0xd800+1)) {
- if (ReadImage(fd,os->image,0xffff-0xe000+1)) {
- status = 1;
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (fdo>=0)
- close(fdo);
-
- if (status) {
- os->secs[0].lo=0xe000;
- os->secs[0].hi=0xffff;
- mpack->secs[0].lo=0xd800;
- mpack->secs[0].hi=0xdfff;
- selftest->secs[0].lo=0x5000;
- selftest->secs[0].hi=0x57ff;
- os_x->secs[0].lo=0xc000;
- os_x->secs[0].hi=0xcfff;
- return TRUE;
- }
-
- if (verbose)
- perror(filename);
-
- FreeCart(os);
- FreeCart(mpack);
- FreeCart(os_x);
- FreeCart(selftest);
-
- os=mpack=os_x=selftest=NULL;
-
- return FALSE;
- }
-
- int ReadBasic(char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0xa000,0xbfff-0xa000+1))!=0) {
- basic=ct;
- return TRUE;
- }
-
- return FALSE;
- }
-
- /*
- * Load a standard 8K ROM from the specified file
- */
- int Insert_8K_ROM (char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0xa000,0xbfff-0xa000+1))!=0) {
- ct->type = NORMAL8_CART;
- RemoveCurrent();
- InsertCart(ct);
- return TRUE;
- }
-
- return FALSE;
- }
-
- /*
- * Load a standard 16K ROM from the specified file
- */
- int Insert_16K_ROM (char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0x8000,0xbfff-0x8000+1))!=0) {
- ct->type = NORMAL16_CART;
- RemoveCurrent();
- InsertCart(ct);
- return TRUE;
- }
-
- return FALSE;
- }
-
- /*
- * Load an OSS Supercartridge from the specified file
- * The OSS cartridge is a 16K bank switched cartridge
- * that occupies 8K of address space between $a000
- * and $bfff
- */
-
- int Insert_OSS_ROM (char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0x8000,0xbfff-0x8000+1))!=0) {
- ct->type = OSS_SUPERCART;
- ct->secs[0].lo = 0xa000;
- ct->secs[0].hi = 0xafff;
- ct->secs[1].lo = 0xa000;
- ct->secs[1].hi = 0xafff;
- ct->secs[1].offset = 0x1000;
- ct->secs[2].lo = 0xa000;
- ct->secs[2].hi = 0xafff;
- ct->secs[2].offset = 0x2000;
- ct->secs[3].lo = 0xb000;
- ct->secs[3].hi = 0xbfff;
- ct->secs[3].offset = 0x3000;
- ct->secs[3].active = TRUE;
- RemoveCurrent();
- InsertCart(ct);
- return TRUE;
- }
-
- return FALSE;
- }
-
-
- /*
- * Load a DB Supercartridge from the specified file
- * The DB cartridge is a 32K bank switched cartridge
- * that occupies 16K of address space between $8000
- * and $bfff
- */
- int Insert_DB_ROM (char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0x2000,0xbfff-0x2000+1))!=0) {
- ct->type = DB_SUPERCART;
- ct->secs[0].lo = 0x8000;
- ct->secs[0].hi = 0x9fff;
- ct->secs[1].lo = 0x8000;
- ct->secs[1].hi = 0x9fff;
- ct->secs[1].offset = 0x2000;
- ct->secs[2].lo = 0x8000;
- ct->secs[2].hi = 0x9fff;
- ct->secs[2].offset = 0x4000;
- ct->secs[3].lo = 0xa000;
- ct->secs[3].hi = 0xbfff;
- ct->secs[3].offset = 0x6000;
- ct->secs[3].active = TRUE;
- RemoveCurrent();
- InsertCart(ct);
- return TRUE;
- }
-
- return FALSE;
- }
-
-
- /*
- * Load a 32K 5200 ROM from the specified file
- *
- * still to be checked
- */
-
- int Insert_32K_5200ROM (char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0x4000,0xbfff-0x4000+1))!=0) {
- ct->type = AGS32_CART;
- RemoveCurrent();
- InsertCart(ct);
- return TRUE;
- }
-
- return FALSE;
- }
-
- int Insert_16K_5200ROM (char *filename,int fd)
- {
- struct Cart *ct;
-
- if ((ct=ReadCart(filename,fd,0x4000,0x7fff-0x4000+1))!=0) {
- ct->type = AGS16_CART;
- /* setup the magic mirroring. Invalidates RAM saveback, but who cares...
- the 5200 doesn't have RAM there anyways */
- ct->secs[0].lo = 0x4000;
- ct->secs[0].hi = 0x5fff;
- ct->secs[0].offset = 0x0000;
- ct->secs[0].active = TRUE;
- ct->secs[1].lo = 0x8000;
- ct->secs[1].hi = 0x9fff;
- ct->secs[1].offset = 0x2000;
- ct->secs[1].active = TRUE;
- ct->secs[2].lo = 0xa000;
- ct->secs[2].hi = 0xbfff;
- ct->secs[2].offset = 0x2000;
- ct->secs[2].active = TRUE;
- ct->secs[3].lo = 0x6000;
- ct->secs[3].hi = 0x7fff;
- ct->secs[3].offset = 0x0000;
- ct->secs[3].active = TRUE;
- RemoveCurrent();
- InsertCart(ct);
- return TRUE;
- }
-
- return FALSE;
- }
-
- static struct Cart *ReadCart(char *filename, int fd,int addr, int nbytes)
- {
- struct Cart *ct;
- int fdo = -1;
- int status=0;
-
- if ((ct=AllocCart(nbytes))!=0) {
- if (filename) {
- fd = fdo = open(filename, O_MODE,0777);
- }
- if (fd>=0) {
- status = ReadImage(fd,ct->image,nbytes);
- }
- }
-
- if (fdo>=0)
- close(fdo);
-
- if (status) {
- ct->secs[0].lo = addr;
- ct->secs[0].hi = addr+nbytes-1;
- return ct;
- }
-
- if (verbose)
- perror(filename);
-
- FreeCart(ct);
- return NULL;
- }
-
-
- int lof(char *filename)
- {
- struct stat buf;
-
- if (stat(filename,&buf)==0) {
- return buf.st_size;
- }
-
- if (verbose)
- perror(filename);
-
- return -1;
- }
-
-
- static void DisableCart(struct Cart *ct)
- {
- int i;
-
- if (ct) {
- if (ct->active) {
- for(i=0;i<4;i++) {
- if (ct->secs[i].active) {
- memcpy(memory+ct->secs[i].lo,ct->saveback+ct->secs[i].offset,(ct->secs[i].hi-ct->secs[i].lo+1)*sizeof(mtype));
- SetRAM(ct->secs[i].lo,ct->secs[i].hi);
- #ifdef DEBUG
- printf("Disabling a cart between %x and %x\n",ct->secs[i].lo,ct->secs[i].hi);
- #endif
- }
- }
- ct->active = FALSE;
- }
- }
- }
-
- static void EnableCart(struct Cart *ct)
- {
- int i;
- int len;
-
- if (ct) {
- if (!(ct->active)) {
- for(i=0;i<4;i++) {
- if (ct->secs[i].active) {
- len = (ct->secs[i].hi-ct->secs[i].lo+1)*sizeof(mtype);
- memcpy(ct->saveback+ct->secs[i].offset,memory+ct->secs[i].lo,len);
- memcpy(memory+ct->secs[i].lo,ct->image+ct->secs[i].offset,len);
- SetROM(ct->secs[i].lo,ct->secs[i].hi);
- #ifdef DEBUG
- printf("Enabling a cart between %x and %x\n",ct->secs[i].lo,ct->secs[i].hi);
- #endif
- }
- }
- ct->active=TRUE;
- }
- }
- }
-
-
- void ChangeMapping(int map0,int map1,int map2, int map3)
- {
- struct Cart *ct=current;
-
- if (ct) {
- /* first, remove all images */
- if (!(ct->active)) {
- if (basic_on) {
- DisableCart(basic); /* if it wasn't active before, we've to turn the
- basic off */
- }
- } else DisableCart(ct);
- ct->active = TRUE; /* enables cartridge as well */
- ct->secs[0].active = map0;
- ct->secs[1].active = map1;
- ct->secs[2].active = map2;
- ct->secs[3].active = map3;
- EnableCart(ct);
- }
- }
-
- void RemoveCart(void)
- {
-
- DisableCart(current);
- current = NULL;
-
- if (basic_on)
- EnableCart(basic);
- }
-
- void RemoveCurrent(void)
- {
- struct Cart *old=current;
-
- if (old) {
- RemoveCart();
- FreeCart(old);
- }
- }
-
- void TurnOffCart(void)
- {
- struct Cart *ct=current;
-
- if (ct) {
- if (ct->active) {
- DisableCart(ct);
- }
- if (basic_on) {
- EnableCart(basic);
- }
- }
- }
-
- void TurnOnCart(void)
- {
- struct Cart *ct=current;
-
- if (ct) {
- if (!(ct->active)) {
- if (basic_on) {
- DisableCart(basic);
- }
-
- EnableCart(ct);
- }
- }
- }
-
- void InsertCart(struct Cart *ct)
- {
- if (ct) {
- DisableCart(basic);
- if (current!=ct) {
- DisableCart(current);
- EnableCart(ct);
- current=ct;
- }
- }
- }
-
-
- int CartInserted(void)
- {
- if (current && current->active)
- return TRUE;
-
- return FALSE;
- }
-
- int CartType(void)
- {
- if (current)
- return current->type;
- else return -1;
- }
-
- void EnableBasic(void)
- {
- basic_on=TRUE;
-
- if (!(CartInserted()))
- EnableCart(basic);
- }
-
- void DisableBasic(void)
- {
- basic_on=FALSE;
-
- if (!(CartInserted()))
- DisableCart(basic);
- }
-
- void EnableOs(void)
- {
- EnableCart(os);
- EnableCart(mpack);
- EnableCart(os_x);
- }
-
- void DisableOs(void)
- {
- DisableCart(os);
- DisableCart(mpack);
- DisableCart(os_x);
- }
-
- void EnableSelftest(void)
- {
- EnableCart(selftest);
- }
-
- void DisableSelftest(void)
- {
- DisableCart(selftest);
- }
-
- void FreeCarts(void)
- {
- FreeCart(basic);
- FreeCart(os);
- FreeCart(os_x);
- FreeCart(selftest);
- FreeCart(mpack);
- FreeCart(current);
- basic=os=os_x=selftest=mpack=current=NULL;
- }
-
- void SelectXEBank(int byte)
- {
- int cpu_flag = (byte & 0x10);
- #ifdef DEBUG
- int antic_flag = (byte & 0x20);
- #endif
- int bank = (byte & 0x0c) >> 2;
- static int xe_bank = -1;
-
- #ifdef DEBUG
- printf ("CPU = %d, ANTIC = %d, XE BANK = %d\n",
- cpu_flag, antic_flag, bank);
- #endif
-
- /*
- * Possible Bank Transitions
- *
- * Main -> Main
- * Main -> Bank1,2,3,4
- * Bank1,2,3,4 -> Main
- * Bank1,2,3,4 -> Bank1,2,3,4
- */
-
- if (cpu_flag) { /* turn off bank */
- if (xe_bank != -1) {
- memcpy (XE_Banks[xe_bank],memory + 0x4000,0x4000);
- memcpy (memory + 0x4000,XE_Banks[5],0x4000);
- xe_bank = -1;
- }
- } else if (bank != xe_bank) { /* turn on bank */
- if (xe_bank == -1) {
- memcpy (XE_Banks[5],memory + 0x4000,0x4000); /* saveback mem */
- } else {
- memcpy (XE_Banks[xe_bank],memory + 0x4000,0x4000); /* saveback bank */
- }
- memcpy (memory+0x4000,XE_Banks[bank],0x4000); /* swap in bank */
- xe_bank = bank;
- }
- }
-
-
- int Free_XE_Banks(void)
- {
- int i;
-
- for(i=0;i<4;i++) {
- if (XE_Banks[i])
- free(XE_Banks[i]);
- }
-
- return TRUE;
- }
-
- int Build_XE_Banks(void)
- {
- int i;
-
- for(i=0;i<4;i++) {
- if (!(XE_Banks[i] = malloc(0x4000*sizeof(mtype))))
- return FALSE;
- }
-
- return TRUE;
- }
-
-
- static int InCart(struct Cart *ct,ATPtr ad,mtype **where)
- {
- int i;
-
- if (ct) {
- for (i=0;i<4;i++) {
- if (ct->secs[i].active) {
- if (ad>=ct->secs[i].lo && ad<=ct->secs[i].hi) {
- *where=ct->image+ct->secs[i].offset+(ad-ct->secs[i].lo);
- return TRUE;
- }
- }
- }
- }
-
- return FALSE;
- }
-
- static mtype *LocationOf(ATPtr ad)
- {
- mtype *in;
-
- if (InCart(os_x,ad,&in))
- return in;
-
- if (InCart(selftest,ad,&in))
- return in;
-
- if (InCart(mpack,ad,&in))
- return in;
-
- if (InCart(os,ad,&in))
- return in;
-
- printf("Invalid ROM address %x while patching.\n",ad);
- Atari800_Exit (FALSE,20);
- return 0;
- }
-
- int RomGet(ATPtr ad)
- {
- return *LocationOf(ad);
- }
-
- int RomDGet(ATPtr ad)
- {
- return RomGet(ad)|(RomGet(ad+1)<<8);
- }
-
- void RomSet(ATPtr ad,int v)
- {
- *LocationOf(ad)=v;
- }
-
-